﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using ActiveStory.IO;
using ActiveStory.DataManager;
using Microsoft.Samples.CustomControls;
using Microsoft.Windows.Controls.Ribbon;

namespace ActiveStory.UI
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : RibbonWindow
    {
        #region Fields
        #region Constants
        const String DRAWMODETEXT = "Drawing";
        const String ERASERMODETEXT = "Point Eraser";
        const String HOTSPOTMODETEXT = "Links";
        const String SELECTMODETEXT = "Selection";
        const String ERASERSTROKEMODETEXT = "Stroke Eraser";
        public enum PenMode { Draw, PointEraser, StrokeEraser, Selection, CreateLink, RemoveLink, StopLink };
        public enum InterafaceStyle { OfficeBlack, OfficeBlue, OfficeSilver, Win7Ribbon, NoRibbon };
        #endregion
        protected SelectionBackElement _selectionElement = null;
        protected Point _startPoint = new Point();
        protected Point _endPoint = new Point();
        private PenMode _penMode = PenMode.Draw;
        private ActiveStory.UI.Commands.CommandStack _inkCanvasCommandStack;
        private int _editingOperationCount = 0;
        private InterafaceStyle _currentInterfaceStyle = InterafaceStyle.OfficeBlack;
        #endregion

        #region Properties
        public PenMode CurrentPenMode
        {
            get
            {
                return _penMode;
            }
        }
        public double EraserWidth
        {
            get
            {
                return CurrentInkCanvas.EraserShape.Width;
            }
            set
            {
                CurrentInkCanvas.EraserShape = new System.Windows.Ink.EllipseStylusShape(value, CurrentInkCanvas.EraserShape.Height);
                InkCanvasEditingMode temp = CurrentInkCanvas.ActiveEditingMode;
                CurrentInkCanvas.EditingMode = InkCanvasEditingMode.None;
                CurrentInkCanvas.EditingMode = temp;
            }
        }
        public double EraserHeight
        {
            get
            {
                return CurrentInkCanvas.EraserShape.Height;
            }
            set
            {
                CurrentInkCanvas.EraserShape = new System.Windows.Ink.EllipseStylusShape(CurrentInkCanvas.EraserShape.Width, value);
                InkCanvasEditingMode temp = CurrentInkCanvas.ActiveEditingMode;
                CurrentInkCanvas.EditingMode = InkCanvasEditingMode.None;
                CurrentInkCanvas.EditingMode = temp;
            }
        }
        public SolidColorBrush PenBrush
        {
            get
            {
                return new SolidColorBrush(CurrentInkCanvas.DefaultDrawingAttributes.Color);
            }
            set
            {
                CurrentInkCanvas.DefaultDrawingAttributes.Color = value.Color;
            }
        }
        public double PenColorRed
        {
            get
            {
                return CurrentInkCanvas.DefaultDrawingAttributes.Color.R;
            }
            set
            {
                CurrentInkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb(CurrentInkCanvas.DefaultDrawingAttributes.Color.A, (byte)value, CurrentInkCanvas.DefaultDrawingAttributes.Color.G, CurrentInkCanvas.DefaultDrawingAttributes.Color.B);
                CurrentColorValue.GetBindingExpression(Button.BackgroundProperty).UpdateTarget();
            }
        }
        public double PenColorGreen
        {
            get
            {
                return CurrentInkCanvas.DefaultDrawingAttributes.Color.G;
            }
            set
            {
                CurrentInkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb(CurrentInkCanvas.DefaultDrawingAttributes.Color.A, CurrentInkCanvas.DefaultDrawingAttributes.Color.R, (byte)value, CurrentInkCanvas.DefaultDrawingAttributes.Color.B);
                CurrentColorValue.GetBindingExpression(Button.BackgroundProperty).UpdateTarget();
            }
        }
        public double PenColorBlue
        {
            get
            {
                return CurrentInkCanvas.DefaultDrawingAttributes.Color.G;
            }
            set
            {
                CurrentInkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb(CurrentInkCanvas.DefaultDrawingAttributes.Color.A, CurrentInkCanvas.DefaultDrawingAttributes.Color.R, CurrentInkCanvas.DefaultDrawingAttributes.Color.G, (byte)value);
                CurrentColorValue.GetBindingExpression(Button.BackgroundProperty).UpdateTarget();
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Shows the project wizard. Set forceQuit to true if the program should quit when the user hits cancel.
        /// activeTabIndex specifies which tab of the project wizard to load on. (0=New Project,1=Open Project)
        /// Subsequently loads the project instance or creates a new one.
        /// </summary>
        /// <param name="activeTabIndex"></param>
        private void SetupProject(int activeTabIndex, bool forceQuit)
        {
            ProjectWizard projectWizard;
            ShowProjectWizard(out projectWizard, activeTabIndex, forceQuit);
            if (projectWizard == null) // User canceled and forceQuit was not true
            {
                return;
            }
            _editingOperationCount = 0;         //zero the editing count if loading a new project or opening one
            if (projectWizard.NewProject)
            {
                ActiveStoryApplication.CreateProjectInstance(projectWizard.ProjectName, projectWizard.ProjectFolder, new Point(projectWizard.DefaultCanvasWidth, projectWizard.DefaultCanvasHeight));
                if(!Properties.Settings.Default.RecentProjects.Contains(projectWizard.ProjectFolder))
                    Properties.Settings.Default.RecentProjects.Insert(0, projectWizard.ProjectFolder);
            }
            else
            {
                ActiveStoryApplication.LoadProjectInstance(projectWizard.ProjectFile);
                if (!Properties.Settings.Default.RecentProjects.Contains(projectWizard.ProjectFile))
                    Properties.Settings.Default.RecentProjects.Insert(0, projectWizard.ProjectFile);
            }

            PageListBox.ItemsSource = ActiveStoryApplication.CurrentProject.PageMetadataList;
            ActiveStoryApplication.ProjectChangeCleanup(CurrentInkCanvas);
            if (PageListBox.Items.Count > 0)    //Project is not empty, load the first page.
                PageListBox.SelectedIndex = 0;
            else            //Project is new or empty, create a new page and increment page counter.
            {
                ActiveStoryApplication.NewPage(CurrentInkCanvas);
                //ActiveStoryApplication.CurrentProject.IncrementPageCounter();//Increment counter since the current page is also being saved
            }
        }

        /// <summary>
        /// Shows the project wizard. Set forceQuit to true if the program should quit when the user hits cancel.
        /// resultProjectWizard is set to null if the user cancels when forceQuit is false.
        /// activeTabIndex specifies which tab of the project wizard to load on. (0=New Project,1=Open Project)
        /// </summary>
        /// <param name="resultProjectWizard"></param>
        /// <param name="activeTabIndex"></param>
        /// <param name="forceQuit"></param>
        public void ShowProjectWizard(out ProjectWizard resultProjectWizard, int activeTabIndex, bool forceQuit)
        {
            bool ValidProject = false;
            ProjectWizard projectWizard = null;
            string tempProjectName = String.Empty;
            string tempProjectFolder = String.Empty;
            string tempProjectFile = String.Empty;
            while (!ValidProject)
            {
                projectWizard = new ProjectWizard();
                projectWizard.MainTabControl.SelectedIndex = activeTabIndex;
                projectWizard.ProjectNameTextBox.Text = tempProjectName;
                projectWizard.OpenProjectFileComboBox.Text = tempProjectFile;
                projectWizard.NewProjectDirectoryTextBox.Text = tempProjectFolder;
                projectWizard.Owner = this;
                if (forceQuit)
                    projectWizard.ShowInTaskbar = true;
                Nullable<bool> result = projectWizard.ShowDialog();
                tempProjectFile = projectWizard.OpenProjectFileComboBox.Text;
                tempProjectFolder = projectWizard.NewProjectDirectoryTextBox.Text;
                tempProjectName = projectWizard.ProjectNameTextBox.Text;
                if (!result.GetValueOrDefault(false))
                {
                    if (forceQuit)
                    {
                        MessageBoxResult quitResult = MessageBox.Show(this, "You must create or open a project to use ActiveStory Enhanced. Do you want to quit ActiveStory Enhanced?", "Quit?", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes);
                        if (quitResult.Equals(MessageBoxResult.Yes))
                        {
                            ActiveStoryApplication.Exit();
                            resultProjectWizard = null;
                            return;     //ActiveStoryApplication.Exit() does not force quit, this line is executed even after exiting. Keep the return to gracefully quit.
                        }
                        continue;
                    }
                    else
                    {
                        resultProjectWizard = null;
                        return;
                    }
                }
                if (projectWizard.NewProject)
                {
                    activeTabIndex = 0;
                    if (projectWizard.ProjectName.Trim().Equals(String.Empty))
                    {
                        MessageBox.Show(this, "Invalid project name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    if (projectWizard.ProjectFolder.Trim().Equals(String.Empty))
                    {
                        MessageBox.Show(this, "Invalid project folder.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    PathValidationRule pvr = new PathValidationRule();
                    ValidationResult validationResult = pvr.Validate(projectWizard.ProjectName, System.Globalization.CultureInfo.CurrentCulture);
                    if (!validationResult.IsValid)
                    {
                        MessageBox.Show(this, "An error occured when creating the project: " + (String)validationResult.ErrorContent, "Error Creating Project", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    validationResult = pvr.Validate(projectWizard.ProjectFolder, System.Globalization.CultureInfo.CurrentCulture);
                    if (!validationResult.IsValid)
                    {
                        MessageBox.Show(this, "An error occured when creating the project: " + (String)validationResult.ErrorContent, "Error Creating Project", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    if (System.IO.File.Exists(FileManager.CreateProjectFileName(projectWizard.ProjectName, projectWizard.ProjectFolder)))
                    {
                        MessageBox.Show(this, "A project with that name already exists in " + projectWizard.ProjectFolder + ". Please choose a different project name or folder", "Project Already Exists", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    if (!System.IO.Directory.Exists(projectWizard.ProjectFolder))
                    {
                        if (MessageBoxResult.Yes == MessageBox.Show(this, "The folder \"" + projectWizard.ProjectFolder + "\" does not exist, do you want to create this folder?", "Folder Does Not Exist", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                        {
                            System.IO.Directory.CreateDirectory(projectWizard.ProjectFolder);
                        }
                        else
                            continue;
                    }
                    if (projectWizard.DefaultCanvasHeight < 0)
                    {
                        MessageBox.Show(this, "Invalid canvas height.", "Error Creating Project", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    if (projectWizard.DefaultCanvasWidth < 0)
                    {
                        MessageBox.Show(this, "Invalid canvas width.", "Error Creating Project", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    ValidProject = true;
                }
                else
                {
                    activeTabIndex = 1;
                    if (projectWizard.ProjectFile.Trim().Equals(String.Empty))
                    {
                        MessageBox.Show(this, "Invalid project file.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    PathValidationRule pvr = new PathValidationRule();
                    ValidationResult validationResult = pvr.Validate(projectWizard.ProjectFile, System.Globalization.CultureInfo.CurrentCulture);
                    if (!validationResult.IsValid)
                    {
                        MessageBox.Show(this, "An error occured when creating the project: " + (String)validationResult.ErrorContent, "Error Creating Project", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    if (!System.IO.File.Exists(projectWizard.ProjectFile))
                    {
                        MessageBox.Show(this, "No project with that name exists in " + System.IO.Path.GetDirectoryName(projectWizard.ProjectFile) + ". Please choose an existing project file.", "Project Does Not Exist", MessageBoxButton.OK, MessageBoxImage.Error);
                        continue;
                    }
                    ValidProject = true;
                }
            }
            resultProjectWizard = projectWizard;
        }
        private void AddButton(double x, double y, double width, double height)
        {
            LinkDialog linkDialog = new LinkDialog(LinkDialog.LinkDialogModes.CreateLink, -1);
            linkDialog.Owner = this;
            if (linkDialog.ShowDialog() == false)
                return;
            int targetPageNumber = linkDialog.TargetPageNumber;
            Button buttonToAdd = new Button();
            buttonToAdd.Name = "Button" + ActiveStoryApplication.CurrentPage.ButtonCounter;
            buttonToAdd.Content = ActiveStoryApplication.CurrentPage.ButtonCounter;
            ActiveStoryApplication.CurrentPage.AddButtonMapping(ActiveStoryApplication.CurrentPage.ButtonCounter, targetPageNumber);
            ActiveStoryApplication.CurrentPage.IncrementButtonCount();
            CurrentInkCanvas.Children.Add(buttonToAdd);
            InkCanvas.SetTop(buttonToAdd, y);
            InkCanvas.SetLeft(buttonToAdd, x);
            buttonToAdd.ToolTip = "Linked to page " + (targetPageNumber + 1);
            buttonToAdd.Width = width;
            buttonToAdd.Height = height;
            buttonToAdd.BorderBrush = Brushes.Black;
            buttonToAdd.BorderThickness = new Thickness(1);
            buttonToAdd.Background = Brushes.Transparent;
            buttonToAdd.Click += new RoutedEventHandler(delegate(object sender2, RoutedEventArgs e2)
                {
                    LinkDialog ld;
                    if (_penMode == PenMode.RemoveLink)
                    {
                        if (ActiveStoryApplication.CurrentPage.ButtonToPageMap.ContainsKey((int)buttonToAdd.Content))
                            ld = new LinkDialog(LinkDialog.LinkDialogModes.RemoveLink, ActiveStoryApplication.CurrentPage.ButtonToPageMap[(int)buttonToAdd.Content]);
                        else
                        {
                            MessageBox.Show(this, "This link is not associated with any page.", "Error, no link.", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                    }
                    else if (!ActiveStoryApplication.CurrentPage.ButtonToPageMap.ContainsKey((int)buttonToAdd.Content))
                        ld = new LinkDialog(LinkDialog.LinkDialogModes.CreateLink, -1);
                    else
                        ld = new LinkDialog(LinkDialog.LinkDialogModes.Both, ActiveStoryApplication.CurrentPage.ButtonToPageMap[(int)buttonToAdd.Content]);
                    ld.Owner = this;
                    if (ld.ShowDialog() == false)
                        return;
                    int newTargetPageNum = ld.TargetPageNumber;
                    if (newTargetPageNum == -1)    //Removed link
                    {
                        ActiveStoryApplication.CurrentPage.RemoveButtonMapping((int)buttonToAdd.Content);
                        buttonToAdd.ToolTip = "Not linked to any page.";
                    }
                    else                            //Changed link
                    {
                        ActiveStoryApplication.CurrentPage.AddButtonMapping((int)buttonToAdd.Content, newTargetPageNum);
                        buttonToAdd.ToolTip = "Linked to page " + (newTargetPageNum + 1);
                    }
                });
            //MessageBox.Show("Button " + ((Button)sender2).Content + " clicked!\nShould show 'Link To' dialog here."); });
        }

        private void UpdatePageNumberLabel()
        {
            PageNumberValueLabel.Content = ActiveStoryApplication.CurrentPage.PageNumber + 1;
        }


        private void ClearRemoveLinkGlow()
        {
            foreach (UIElement item in CurrentInkCanvas.Children)
            {
                if (item.GetType() == typeof(Button))
                {
                    item.Effect = null;
                }
            }
        }

        /// <summary>
        /// Switches the interface style to the given style. If isRibbon is true,
        /// and style is not null the style will be applied. If style is null, the Windows 7
        /// Ribbon style will be applied. If isRibbon is false, the standard WPF style is applied.
        /// </summary>
        /// <param name="isRibbon"></param>
        /// <param name="style"></param>
        private void SwitchInterfaceStyle(InterafaceStyle newInterfaceStyle)
        {
            switch (newInterfaceStyle)
            {
                case InterafaceStyle.OfficeBlack:
                    if (Application.Current.Resources.MergedDictionaries.Count == 1)   //No style exists in the list.
                    {
                        Application.Current.Resources.MergedDictionaries.Add(PopularApplicationSkins.Office2007Black);
                    }
                    else
                    {
                        Application.Current.Resources.MergedDictionaries[1] = PopularApplicationSkins.Office2007Black;
                    }
                    break;
                case InterafaceStyle.OfficeBlue:
                    if (Application.Current.Resources.MergedDictionaries.Count == 1)   //No style exists in the list.
                    {
                        Application.Current.Resources.MergedDictionaries.Add(PopularApplicationSkins.Office2007Blue);
                    }
                    else
                    {
                        Application.Current.Resources.MergedDictionaries[1] = PopularApplicationSkins.Office2007Blue;

                    }
                    break;
                case InterafaceStyle.OfficeSilver:
                    if (Application.Current.Resources.MergedDictionaries.Count == 1)   //No style exists in the list.
                    {
                        Application.Current.Resources.MergedDictionaries.Add(PopularApplicationSkins.Office2007Silver);
                    }
                    else
                    {
                        Application.Current.Resources.MergedDictionaries[1] = PopularApplicationSkins.Office2007Silver;
                    }
                    break;
                case InterafaceStyle.Win7Ribbon:
                    if (Application.Current.Resources.MergedDictionaries.Count > 1)   //No style exists in the list.
                        Application.Current.Resources.MergedDictionaries.RemoveAt(1);
                    break;
                case InterafaceStyle.NoRibbon:
                    if (Application.Current.Resources.MergedDictionaries.Count > 1)   //No style exists in the list.
                    {
                        Application.Current.Resources.MergedDictionaries.RemoveAt(1);
                    }
                    this.IconVisibility = Visibility.Visible;
                    MainRibbonMenu.Visibility = Visibility.Collapsed;
                    StandardMenu.Visibility = Visibility.Visible;
                    ToolsExpander.Visibility = Visibility.Visible;
                    ColumnDefinition cd = new ColumnDefinition();
                    cd.Width = new GridLength(95);
                    PagesPanel.ColumnDefinitions[0] = cd;
                    cd = new ColumnDefinition();
                    cd.Width = new GridLength(95);
                    PagesPanel.ColumnDefinitions[1] = cd;
                    AddPageButton.Visibility = Visibility.Visible;
                    DeletePageButton.Visibility = Visibility.Visible;
                    _currentInterfaceStyle = newInterfaceStyle;
                    CommandManager.InvalidateRequerySuggested();
                    return;
                default:
                    break;
            }

            //Only executed if a ribbon style is selected
            this.IconVisibility = Visibility.Collapsed;
            MainRibbonMenu.Visibility = Visibility.Visible;
            StandardMenu.Visibility = Visibility.Collapsed;
            ToolsExpander.Visibility = Visibility.Collapsed;
            AddPageButton.Visibility = Visibility.Collapsed;
            DeletePageButton.Visibility = Visibility.Collapsed;
            ColumnDefinition columnDef = new ColumnDefinition();
            columnDef.Width = new GridLength(0);
            PagesPanel.ColumnDefinitions[0] = columnDef;
            columnDef = new ColumnDefinition();
            columnDef.Width = new GridLength(0);
            PagesPanel.ColumnDefinitions[1] = columnDef;
            _currentInterfaceStyle = newInterfaceStyle;
            CommandManager.InvalidateRequerySuggested();
            return;
        }


        private void ApplySettings()
        {
            switch (Properties.Settings.Default.InterfaceStyle)
            {
                case "OfficeBlack":
                    SwitchInterfaceStyle(InterafaceStyle.OfficeBlack);
                    break;
                case "OfficeBlue":
                    SwitchInterfaceStyle(InterafaceStyle.OfficeBlue);
                    break;
                case "OfficeSilver":
                    SwitchInterfaceStyle(InterafaceStyle.OfficeSilver);
                    break;
                case "Win7Ribbon":
                    SwitchInterfaceStyle(InterafaceStyle.Win7Ribbon);
                    break;
                case "NoRibbon":
                    SwitchInterfaceStyle(InterafaceStyle.NoRibbon);
                    break;
            }
            if (Properties.Settings.Default.RecentProjects == null)
            {
                Properties.Settings.Default.RecentProjects = new System.Collections.Specialized.StringCollection();
            }
            if (Properties.Settings.Default.WindowState != WindowState.Minimized)
            {
                WindowState = Properties.Settings.Default.WindowState;
            }
            Width = Properties.Settings.Default.Width;
            Height = Properties.Settings.Default.Height;
            try
            {
                if (Properties.Settings.Default.Left < 0)
                    Left = 0;
                else
                    Left = Properties.Settings.Default.Left;
                
            }
            catch (NullReferenceException)
            {
                //Don't set the left value of the window, let it automatically set itself.
            }
            try
            {
                if (Properties.Settings.Default.Top < 0)
                    Top = 0;
                else
                    Top = Properties.Settings.Default.Top;
            }
            catch (NullReferenceException)
            {
                //Don't set the top value of the window, let it automatically set itself.
            }
            if (Properties.Settings.Default.LeftHanded)
            {
                ApplyUILeftyTransforms();
            }
        }
        private void ApplyUILeftyTransforms()
        {
            BottomPanel.LayoutTransform = new RotateTransform(180);
            foreach (FrameworkElement item in BottomPanel.Children)
            {
                item.LayoutTransform = new RotateTransform(180);
            }
            
            FrameworkElement feToolsExpander = (FrameworkElement)ToolsExpander.Content;
            feToolsExpander.LayoutTransform = new RotateTransform(180);
            DrawButton.LayoutTransform = new RotateTransform(180);
            EraseButton.LayoutTransform = new RotateTransform(180);
            EraseByStrokeButton.LayoutTransform = new RotateTransform(180);
            SelectionModeButton.LayoutTransform = new RotateTransform(180);
            CreateLinkButton.LayoutTransform = new RotateTransform(180);
            RemoveLinkButton.LayoutTransform = new RotateTransform(180);
            ImportImageButton.LayoutTransform = new RotateTransform(180);
            ExportButton.LayoutTransform = new RotateTransform(180);
            
            ColorGrid.LayoutTransform = new RotateTransform(180);
            foreach (FrameworkElement item in ColorGrid.Children)
            {
                item.LayoutTransform = new RotateTransform(180);
            }

            PagesPanel.LayoutTransform = new RotateTransform(180);
            foreach (FrameworkElement item in PagesPanel.Children)
            {
                item.LayoutTransform = new RotateTransform(180);
            }

            LeftyModeMenuItem.IsChecked = Properties.Settings.Default.LeftHanded;
            LeftyModeRibbonToggleButton.IsChecked = Properties.Settings.Default.LeftHanded;
            CommandManager.InvalidateRequerySuggested();
        }

        private void ApplyUIRightyTransforms()
        {
            BottomPanel.LayoutTransform = null ;
            foreach (FrameworkElement item in BottomPanel.Children)
            {
                item.LayoutTransform = null;
            }
            
            FrameworkElement feToolsExpander = (FrameworkElement)ToolsExpander.Content;
            feToolsExpander.LayoutTransform = null;
            DrawButton.LayoutTransform = null;
            EraseButton.LayoutTransform = null;
            EraseByStrokeButton.LayoutTransform = null;
            SelectionModeButton.LayoutTransform = null;
            CreateLinkButton.LayoutTransform = null;
            RemoveLinkButton.LayoutTransform = null;
            ImportImageButton.LayoutTransform = null;
            ExportButton.LayoutTransform = null;

            ColorGrid.LayoutTransform = null;
            foreach (FrameworkElement item in ColorGrid.Children)
            {
                item.LayoutTransform = null;
            }

            PagesPanel.LayoutTransform = null;
            foreach (FrameworkElement item in PagesPanel.Children)
            {
                item.LayoutTransform = null;
            }

            LeftyModeMenuItem.IsChecked = Properties.Settings.Default.LeftHanded;
            LeftyModeRibbonToggleButton.IsChecked = Properties.Settings.Default.LeftHanded;
            CommandManager.InvalidateRequerySuggested();
        }

        private void SaveSettings()
        {
            Properties.Settings.Default.InterfaceStyle = _currentInterfaceStyle.ToString();
            if (Properties.Settings.Default.RecentProjects.Count > 10)
            {
                while (Properties.Settings.Default.RecentProjects.Count > 10)
                {
                    Properties.Settings.Default.RecentProjects.RemoveAt(Properties.Settings.Default.RecentProjects.Count - 1);
                }
            }
            Properties.Settings.Default.WindowState = WindowState;
            if (WindowState == WindowState.Normal)
            {
                Properties.Settings.Default.Width = Width;
                Properties.Settings.Default.Height = Height;
                Properties.Settings.Default.Left = Left;
                Properties.Settings.Default.Top = Top;
            }
            Properties.Settings.Default.Save();
        }

        //private void UpdateToggleButtons(object sender, RoutedEventArgs e)
        //{
        //    if (_disabledButton == e.Source as Button)
        //    {
        //        return;
        //    }
        //    Button temp = null;
        //    if (_disabledButton != null)
        //        temp = _disabledButton;
        //    _disabledButton = e.Source as Button;
        //    _disabledButton.IsEnabled = false;
        //    if (temp != null)
        //        temp.IsEnabled = true;
        //}
        #endregion

        #region Constructors
        public MainWindow()
        {
            InitializeComponent();
            #region Initial Values
            EraserWidthSlider.Value = CurrentInkCanvas.EraserShape.Width;
            EraserHeightSlider.Value = CurrentInkCanvas.EraserShape.Height;
            CurrentColorValue.Background = PenBrush;
            ColorRedSlider.Value = PenColorRed;
            ColorGreenSlider.Value = PenColorGreen;
            ColorBlueSlider.Value = PenColorBlue;
            #endregion
            #region Bindings
            Binding binding = new Binding();
            binding.Path = new PropertyPath("EraserWidth");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            EraserWidthSlider.SetBinding(Slider.ValueProperty, binding);
            binding = new Binding();
            binding.Path = new PropertyPath("EraserHeight");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            EraserHeightSlider.SetBinding(Slider.ValueProperty, binding);
            binding = new Binding();
            binding.Path = new PropertyPath("PenColorRed");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            ColorRedSlider.SetBinding(Slider.ValueProperty, binding);
            binding = new Binding();
            binding.Path = new PropertyPath("PenColorGreen");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            ColorGreenSlider.SetBinding(Slider.ValueProperty, binding);
            binding = new Binding();
            binding.Path = new PropertyPath("PenColorBlue");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            ColorBlueSlider.SetBinding(Slider.ValueProperty, binding);
            binding = new Binding();
            binding.Path = new PropertyPath("PenBrush");
            binding.Source = this;
            binding.Mode = BindingMode.TwoWay;
            CurrentColorValue.SetBinding(Button.BackgroundProperty, binding);
            #endregion
            CurrentInkCanvas.DefaultDrawingAttributes.FitToCurve = true;
            _inkCanvasCommandStack = new ActiveStory.UI.Commands.CommandStack(CurrentInkCanvas.Strokes);
            CurrentInkCanvas.Strokes.StrokesChanged += new System.Windows.Ink.StrokeCollectionChangedEventHandler(Strokes_StrokesChanged);
        }
        #endregion

        #region Window Event Handlers
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            ApplySettings();
            SetupProject(0, true);
            
        }


        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            MessageBoxResult mbr = MessageBox.Show(this, "Do you want to save your project?", "Save Project", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (mbr.Equals(MessageBoxResult.Yes))
            {
                PageListBox.SelectedIndex = -1;     //Unselect the list items to avoid multiselect problems
                ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when saving page
                ActiveStoryApplication.SaveCurrentPage(CurrentInkCanvas);
                ActiveStoryApplication.SaveProject();
            }
            mbr = MessageBox.Show(this, "Are you sure you want to exit?", "Confirm Exit", MessageBoxButton.YesNo, MessageBoxImage.Question);
            if (mbr.Equals(MessageBoxResult.No))
                e.Cancel = true;
            SaveSettings();
        }
        private void PageListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (PageListBox.SelectedIndex == -1)
                return;
            ActiveStoryPageMetadata selected = (ActiveStoryPageMetadata)PageListBox.SelectedItem;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing page
            ActiveStoryApplication.SelectPage(CurrentInkCanvas, selected.PageNumber, this);
            _editingOperationCount = 0;
            UpdatePageNumberLabel();
        }
        private void CurrentInkCanvas_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (_penMode != PenMode.CreateLink)
                return;
            _startPoint = new Point(e.GetPosition(CurrentInkCanvas).X, e.GetPosition(CurrentInkCanvas).Y);
        }
        private void CurrentInkCanvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (_penMode != PenMode.CreateLink)
            {
                return;
            }
            _endPoint = new Point(e.GetPosition(CurrentInkCanvas).X, e.GetPosition(CurrentInkCanvas).Y);
            if (_startPoint.X > _endPoint.X)
            {
                double temp = _startPoint.X;
                _startPoint.X = _endPoint.X;
                _endPoint.X = temp;
            }
            if (_startPoint.Y > _endPoint.Y)
            {
                double temp = _startPoint.Y;
                _startPoint.Y = _endPoint.Y;
                _endPoint.Y = temp;
            }
            AddButton(_startPoint.X, _startPoint.Y, Math.Abs(_endPoint.X - _startPoint.X), Math.Abs(_endPoint.Y - _startPoint.Y));
            CurrentInkCanvas.Children.Remove(_selectionElement);
            _selectionElement = null;
            _penMode = PenMode.StopLink;
            UI.Commands.UICommands.DrawMode.Execute(null, this);
            //_hotSpotMode = false;
            //CreateLinkButton.IsEnabled = true;
            //CurrentInkCanvas.EditingMode = InkCanvasEditingMode.Ink; // TODO: reset to current mode
            //_penMode = PenMode.Draw;
            //DrawButton.IsEnabled = false;
            //_disabledButton = DrawButton;
        }
        private void CurrentInkCanvas_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Delete)
            {
                System.Collections.ObjectModel.ReadOnlyCollection<UIElement> elements = CurrentInkCanvas.GetSelectedElements();
                if (CurrentInkCanvas.GetSelectedElements().Count <= 0)
                    return;
                foreach (UIElement item in elements)
                {
                    if (item.GetType() != typeof(Button))
                        continue;
                    Button tempButton = (Button)item;
                    ActiveStoryApplication.CurrentPage.RemoveButtonMapping((int)tempButton.Content);
                }
            }
        }
        #endregion

        #region Old Handlers -Commented
        //private void AddPageButton_Click(object sender, RoutedEventArgs e)
        //{
        //    PageListBox.SelectedIndex = -1;     //Unselect the list items to avoid multiselect problems
        //    ActiveStoryApplication.NewPage(CurrentInkCanvas);
        //}

        //private void DeletePageButton_Click(object sender, RoutedEventArgs e)
        //{
        //    PageListBox.SelectedIndex = -1;
        //    ActiveStoryApplication.RemovePage(CurrentInkCanvas);
        //}



        //private void CreateLinkButton_Click(object sender, RoutedEventArgs e)
        //{
        //    ModeValueLabel.Content = HOTSPOTMODETEXT;
        //    UpdateToggleButtons(sender, e);
        //    _hotSpotMode = true;
        //    _selectionElement = new SelectionBackElement(CurrentInkCanvas);
        //    CurrentInkCanvas.Children.Add(_selectionElement);
        //    CreateLinkButton.IsEnabled = false;
        //    CurrentInkCanvas.EditingMode = InkCanvasEditingMode.None;
        //}



        //private void DrawButton_Click(object sender, RoutedEventArgs e)
        //{
        //    CurrentInkCanvas.EditingMode = InkCanvasEditingMode.Ink;
        //    ModeValueLabel.Content = DRAWMODETEXT;
        //    UpdateToggleButtons(sender, e);
        //}

        //private void Erase_Click(object sender, RoutedEventArgs e)
        //{
        //    CurrentInkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
        //    ModeValueLabel.Content = ERASERMODETEXT;
        //    UpdateToggleButtons(sender, e);
        //}

        //private void EraseByStrokeButton_Click(object sender, RoutedEventArgs e)
        //{
        //    CurrentInkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
        //    ModeValueLabel.Content = ERASERSTROKEMODETEXT;
        //    UpdateToggleButtons(sender, e);
        //}

        //private void SelectionModeButton_Click(object sender, RoutedEventArgs e)
        //{
        //    CurrentInkCanvas.EditingMode = InkCanvasEditingMode.Select;
        //    ModeValueLabel.Content = SELECTMODETEXT;
        //    UpdateToggleButtons(sender, e);
        //}

        //private void ImportImageButton_Click(object sender, RoutedEventArgs e)
        //{
        //    Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
        //    ofd.Filter = "Image Files (*.png;*.jpg;*.gif;*.bmp)|*.png;*.jpg;*.gif;*.bmp";
        //    ofd.Multiselect = false;
        //    ofd.AddExtension = true;
        //    ofd.FilterIndex = 0;
        //    ofd.CheckPathExists = true;
        //    ofd.ValidateNames = true;
        //    ofd.Title = "Select an image file to import.";
        //    if ((bool)ofd.ShowDialog(this) != true)
        //    {
        //        return;
        //    }
        //    Image img = new Image();
        //    img.Source = new BitmapImage(new Uri(ofd.FileName));

        //    CurrentInkCanvas.Children.Add(img);
        //}

        //private void CurrentColorValue_Click(object sender, RoutedEventArgs e)
        //{
        //    ColorPickerDialog cpd = new ColorPickerDialog();
        //    cpd.StartingColor = CurrentInkCanvas.DefaultDrawingAttributes.Color;
        //    cpd.WindowStartupLocation = WindowStartupLocation.CenterOwner;
        //    cpd.Height = cpd.Height + 20;
        //    cpd.Owner = this;
        //    if ((bool)cpd.ShowDialog() != true)
        //        return;

        //    ColorRedSlider.Value = cpd.SelectedColor.R;
        //    ColorGreenSlider.Value = cpd.SelectedColor.G;
        //    ColorBlueSlider.Value = cpd.SelectedColor.B;
        //    CurrentInkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb(cpd.SelectedColor.A, cpd.SelectedColor.R, cpd.SelectedColor.G, cpd.SelectedColor.B);
        //}

        //private void FileExitMenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    this.Close();
        //}

        //private void HelpAboutMenuItem_Click(object sender, RoutedEventArgs e)
        //{
        //    AboutWindow aboutWindow = new AboutWindow();
        //    aboutWindow.Owner = this;
        //    aboutWindow.ShowDialog();
        //}

        #endregion

        #region Command Event Handlers
        private void NewProjectCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SetupProject(0, false);
        }



        private void NewProjectCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void OpenProjectCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SetupProject(1, false);
        }

        private void OpenProjectCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void SaveProjectCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            PageListBox.SelectedIndex = -1;     //Unselect the list items to avoid multiselect problems
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when saving page
            ActiveStoryApplication.SaveCurrentPage(CurrentInkCanvas);
            ActiveStoryApplication.SaveProject();
        }

        private void SaveProjectCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void ExportProjectCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            bool reprompt = true;
            String directory = String.Empty;
            String taskInstructions = String.Empty;
            int selectedTabIndex=-1;
            if (e.Parameter != null)
                selectedTabIndex = int.Parse((String)e.Parameter);
            else
                selectedTabIndex = 0;
            while (reprompt)
            {
                ExportWindow ew = new ExportWindow();
                ew.Owner = this;
                ew.ExportTabControl.SelectedIndex = selectedTabIndex;
                ew.WoZExportDirectoryTextBox.Text = directory;
                ew.ExportAllDirectoryTextBox.Text = directory;
                ew.PageExportDirectoryTextBox.Text = directory;
                ew.TaskInstructionsTextBox.Text = taskInstructions;
                if (!ActiveStoryApplication.CurrentProject.PageLookupTable.ContainsKey(ActiveStoryApplication.CurrentPage.PageNumber))
                    ew.CurrentPageTabItem.IsEnabled = false;
                try
                {

                    if (!(bool)ew.ShowDialog())
                        return;
                }
                catch (Exception exc)
                {
                    continue;
                }
                taskInstructions = ew.TaskInstructionsTextBox.Text;
                switch (ew.SelectedExportMode)
                {
                    case ExportWindow.ExportMode.WizardOfOz:
                        directory = ew.WoZExportDirectoryTextBox.Text;
                        selectedTabIndex = 0;
                        switch (ew.SelectedServerHostType)
                        {
                            case ActiveStoryApplication.ServerHostType.BuiltIn:
                                if (ew.SelectedStartupPageNumber < 0)
                                {
                                    MessageBox.Show(this, "Invalid startup page number.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                    continue;
                                }
#if !DEBUG
                                try
                                {
#endif
                                    ActiveStoryApplication.ExportToSilverlightWizardOfOz(ew.TargetDirectory, ew.SelectedServerHostType, ew.SelectedStartupPageNumber, ew.TaskInstructions);
#if !DEBUG
                                }
                                catch
                                {
                                    MessageBox.Show(this, "An error occured when exporting to the Wizard of Oz Tool. Please make sure UltiDev Cassini is installed and running. If you continue to experience issues, run ActiveStory in Administrator mode.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                    continue;
                                }
#endif
                                string link = "http://localhost:" + int.Parse(ew.TargetDirectory);
                                MessageBox.Show(this, "Export to Silverlight completed. Silverlight Wizard of Oz Export located at: " + link + " Test reports can be browsed at: " + link + "/Reports.aspx", "Export Completed", MessageBoxButton.OK, MessageBoxImage.Information);
                                reprompt = false;
                                return;
                            case ActiveStoryApplication.ServerHostType.External:
                                if (ew.TargetDirectory.Trim().Length == 0)
                                    continue;
                                if (!System.IO.Directory.Exists(ew.TargetDirectory))
                                {
                                    if (MessageBoxResult.Yes == MessageBox.Show(this, "The folder \"" + ew.TargetDirectory + "\" does not exist, do you want to create this folder?", "Folder Does Not Exist", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.Yes))
                                    {
                                        System.IO.Directory.CreateDirectory(ew.TargetDirectory);
                                    }
                                    else
                                        continue;
                                }
                                if (ew.SelectedStartupPageNumber < 0)
                                {
                                    MessageBox.Show(this, "Invalid startup page number.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                    continue;
                                }
#if !DEBUG
                                try
                                {
#endif
                                    ActiveStoryApplication.ExportToSilverlightWizardOfOz(ew.TargetDirectory, ew.SelectedServerHostType, ew.SelectedStartupPageNumber, ew.TaskInstructions);
#if !DEBUG
                                }
                                catch
                                {
                                    MessageBox.Show(this, "An error occured when exporting to the Wizard of Oz Tool.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                    continue;
                                }
#endif
                                MessageBox.Show(this, "Export to Silverlight completed. Silverlight Wizard of Oz Export located at: " + ew.TargetDirectory, "Export Completed", MessageBoxButton.OK, MessageBoxImage.Information);
                                reprompt = false;
                                return;
                            case ActiveStoryApplication.ServerHostType.Error:
                                reprompt = true;
                                continue;
                            default:
                                continue;
                        }
                        continue;
                    case ExportWindow.ExportMode.CurrentPage:
                        directory = ew.PageExportDirectoryTextBox.Text;
                        selectedTabIndex = 1;
                        if (ew.TargetDirectory.Trim().Length == 0)
                            continue;
                        ActiveStoryApplication.ExportCurrentPageToImage(ew.TargetDirectory, ew.SelectedImageFormat);
                        MessageBox.Show(this, "Export to image completed. Image located at: " + ew.TargetDirectory, "Export Completed", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    case ExportWindow.ExportMode.AllPages:
                        directory = ew.PageExportDirectoryTextBox.Text;
                        selectedTabIndex = 2;
                        if (ew.TargetDirectory.Trim().Length == 0)
                            continue;
                        ActiveStoryApplication.ExportAllPageToImages(ew.TargetDirectory, ew.SelectedImageFormat);
                        MessageBox.Show(this, "Export all pages to images completed. Images located at: " + ew.TargetDirectory, "Export Completed", MessageBoxButton.OK, MessageBoxImage.Information);
                        return;
                    case ExportWindow.ExportMode.Error:
                        reprompt = true;
                        continue;
                    default:
                        continue;
                }
            }
        }

        private void ExportProjectCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            if (ActiveStoryApplication.CurrentProject != null)
            {
                if (ActiveStoryApplication.CurrentProject.PageLookupTable.Count == 0)
                {
                    e.CanExecute = false;
                    return;
                }
            }
            else            //Project is null, dont allow export
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void ExitActiveStoryCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        private void ExitActiveStoryCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void DrawModeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.Ink;
            ModeValueLabel.Content = DRAWMODETEXT;
            _penMode = PenMode.Draw;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing pen mode
        }

        private void DrawModeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink || _penMode == PenMode.Draw)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void PointEraserModeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.EraseByPoint;
            ModeValueLabel.Content = ERASERMODETEXT;
            _penMode = PenMode.PointEraser;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing pen mode
        }

        private void PointEraserModeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink || _penMode == PenMode.PointEraser)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void StrokeEraserModeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.EraseByStroke;
            ModeValueLabel.Content = ERASERSTROKEMODETEXT;
            _penMode = PenMode.StrokeEraser;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing pen mode
        }

        private void StrokeEraserModeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink || _penMode == PenMode.StrokeEraser)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void SelectionModeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.Select;
            ModeValueLabel.Content = SELECTMODETEXT;
            _penMode = PenMode.Selection;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing pen mode
        }

        private void SelectionModeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink || _penMode == PenMode.Selection)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void CreateLinkCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                CurrentInkCanvas.Children.Remove(_selectionElement);
                _selectionElement = null;
                _penMode = PenMode.StopLink;
                UI.Commands.UICommands.DrawMode.Execute(null, this);
                return;
            }
            ModeValueLabel.Content = HOTSPOTMODETEXT;
            _penMode = PenMode.CreateLink;
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when changing pen mode
            _selectionElement = new SelectionBackElement(CurrentInkCanvas);
            CurrentInkCanvas.Children.Add(_selectionElement);
            //CreateLinkButton.IsEnabled = false;
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.None;
        }

        private void CreateLinkCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void RemoveLinkCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            _penMode = PenMode.RemoveLink;
            foreach (UIElement item in CurrentInkCanvas.Children)
            {
                if (item.GetType() == typeof(Button))
                {
                    //System.Windows.Media.Effects.OuterGlowBitmapEffect effect = new System.Windows.Media.Effects.OuterGlowBitmapEffect();
                    System.Windows.Media.Effects.DropShadowEffect effect = new System.Windows.Media.Effects.DropShadowEffect();
                    effect.Color = Colors.Red;
                    effect.ShadowDepth = 0;
                    item.Effect = effect;
                }
            }
            CurrentInkCanvas.EditingMode = InkCanvasEditingMode.None;
        }

        private void RemoveLinkCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink || _penMode == PenMode.RemoveLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void ImportImageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.Filter = "Image Files (*.png;*.jpg;*.gif;*.bmp)|*.png;*.jpg;*.gif;*.bmp";
            ofd.Multiselect = false;
            ofd.AddExtension = true;
            ofd.FilterIndex = 0;
            ofd.CheckPathExists = true;
            ofd.ValidateNames = true;
            ofd.Title = "Select an image file to import.";
            if ((bool)ofd.ShowDialog(this) != true)
            {
                return;
            }
            if (!System.IO.File.Exists(FileManager.GetAbsolutePath(System.IO.Path.GetFileName(ofd.FileName))))
                System.IO.File.Copy(ofd.FileName, FileManager.GetAbsolutePath(System.IO.Path.GetFileName(ofd.FileName)));
            Image img = new Image();
            img.Source = new BitmapImage(new Uri(FileManager.GetAbsolutePath(System.IO.Path.GetFileName(ofd.FileName))));

            CurrentInkCanvas.Children.Add(img);
        }

        private void ImportImageCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }

        private void AddPageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            PageListBox.SelectedIndex = -1;     //Unselect the list items to avoid multiselect problems
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when saving page
            ActiveStoryApplication.NewPage(CurrentInkCanvas);
            UpdatePageNumberLabel();
        }

        private void AddPageCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void DeletePageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            PageListBox.SelectedIndex = -1;
            ActiveStoryApplication.RemovePage(CurrentInkCanvas);
            ActiveStoryApplication.SaveProject();
            UpdatePageNumberLabel();
            if (PageListBox.Items.Count > 0)
                PageListBox.SelectedIndex = PageListBox.Items.Count - 1;
        }

        private void DeletePageCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void CarbonCopyPageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ClearRemoveLinkGlow();      //Remove the glow from Remove Link mode when saving page
            System.Windows.Ink.StrokeCollection tempInkCanvasStrokes = CurrentInkCanvas.Strokes.Clone();
            //UIElementCollection tempInkCanvasElements =new UIElementCollection();
            UIElement[] tempInkCanvasElements = new UIElement[CurrentInkCanvas.Children.Count];
            CurrentInkCanvas.Children.CopyTo(tempInkCanvasElements, 0);
            Point tempCurrentCanvasSize = ActiveStoryApplication.CurrentCanvasSize;
            AddPageCommandBinding.Command.Execute(null);
            ActiveStoryApplication.SetCanvasSize(CurrentInkCanvas, tempCurrentCanvasSize);
            CurrentInkCanvas.Strokes.Add(tempInkCanvasStrokes);
            foreach (UIElement item in tempInkCanvasElements)
            {
                CurrentInkCanvas.Children.Add(item);
            }
            MessageBox.Show(this, "Carbon copy complete.", "Carbon Copy Completed", MessageBoxButton.OK, MessageBoxImage.Information);
        }

        private void CarbonCopyPageCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void RenamePageCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            RenamePageDialog rpd = new RenamePageDialog(ActiveStoryApplication.CurrentPage.PageName, ActiveStoryApplication.CurrentPage.PageNumber);
            rpd.Owner = this;
            if (rpd.ShowDialog() != true)
                return;
            ActiveStoryApplication.SetCurrentPageName(rpd.NewName);
        }

        private void RenamePageCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void SetPenColorCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ColorPickerDialog cpd = new ColorPickerDialog();
            cpd.StartingColor = CurrentInkCanvas.DefaultDrawingAttributes.Color;
            cpd.WindowStartupLocation = WindowStartupLocation.CenterOwner;
            cpd.Height = cpd.Height + 20;
            cpd.Owner = this;
            if ((bool)cpd.ShowDialog() != true)
                return;

            //ColorRedSlider.Value = cpd.SelectedColor.R;
            //ColorGreenSlider.Value = cpd.SelectedColor.G;
            //ColorBlueSlider.Value = cpd.SelectedColor.B;

            CurrentInkCanvas.DefaultDrawingAttributes.Color = Color.FromArgb(cpd.SelectedColor.A, cpd.SelectedColor.R, cpd.SelectedColor.G, cpd.SelectedColor.B);
            ColorRedSlider.GetBindingExpression(Slider.ValueProperty).UpdateTarget();
            ColorGreenSlider.GetBindingExpression(Slider.ValueProperty).UpdateTarget();
            ColorBlueSlider.GetBindingExpression(Slider.ValueProperty).UpdateTarget();
            CurrentColorValue.GetBindingExpression(Button.BackgroundProperty).UpdateTarget();
        }

        private void SetPenColorCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void SetCanvasSizeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CanvasSizeDialog csd = new CanvasSizeDialog(ActiveStoryApplication.CurrentCanvasSize);
            csd.Owner = this;
            if (csd.ShowDialog() != true)
                return;
            ActiveStoryApplication.SetCanvasSize(CurrentInkCanvas, csd.CanvasSize);
            if (csd.SetDefault)
            {
                ActiveStoryApplication.CurrentProject.DefaultCanvasSize = csd.CanvasSize;
            }
        }

        private void SetCanvasSizeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void AboutCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AboutWindow aboutWindow = new AboutWindow();
            aboutWindow.Owner = this;
            aboutWindow.ShowDialog();
        }

        private void BlueRibbonStyleCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SwitchInterfaceStyle(InterafaceStyle.OfficeBlue);
        }

        private void BlueRibbonStyleCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void BlackRibbonStyleCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SwitchInterfaceStyle(InterafaceStyle.OfficeBlack);
        }

        private void BlackRibbonStyleCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void SilverRibbonStyleCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SwitchInterfaceStyle(InterafaceStyle.OfficeSilver);
        }

        private void SilverRibbonStyleCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void Win7RibbonStyleCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SwitchInterfaceStyle(InterafaceStyle.Win7Ribbon);
        }

        private void Win7RibbonStyleCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void NoRibbonStyleCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SwitchInterfaceStyle(InterafaceStyle.NoRibbon);
        }

        private void NoRibbonStyleCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }

        private void InterfaceMenu_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = true;
        }


        private void LeftyModeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            if (sender == null)
                return;
            if (e.OriginalSource.GetType() == typeof(RibbonToggleButton))
            {
                RibbonToggleButton tempRTB = (RibbonToggleButton)e.OriginalSource;
                Properties.Settings.Default.LeftHanded = (bool)tempRTB.IsChecked;
            }
            else if (e.OriginalSource.GetType() == typeof(MenuItem))
            {
                MenuItem tempMenuItem = (MenuItem)e.OriginalSource;
                Properties.Settings.Default.LeftHanded = tempMenuItem.IsChecked;
            }
            else
                return;
            if (Properties.Settings.Default.LeftHanded)
                ApplyUILeftyTransforms();
            else
                ApplyUIRightyTransforms();
        }

        private void LeftyModeCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_penMode == PenMode.CreateLink)
            {
                e.CanExecute = false;
                return;
            }
            e.CanExecute = true;
        }
        #endregion

        #region Undo / Redo Code (From Microsoft InkCanvasEditingMode Sample)
        /// <summary>
        /// Undo the last edit.
        /// </summary>
        private void Undo()
        {
            _inkCanvasCommandStack.Undo();
        }

        /// <summary>
        /// Redo the last edit.
        /// </summary>
        private void Redo()
        {
            _inkCanvasCommandStack.Redo();
        }

        /// <summary>
        /// Undo last command
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void UndoCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Undo();
        }

        private void UndoCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_inkCanvasCommandStack == null)
            {
                e.CanExecute = false;
                return;
            }
            // Enable only if there are items on the command stack
            e.CanExecute = _inkCanvasCommandStack.CanUndo;
        }

        /// <summary>
        /// Redo last command
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void RedoCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Redo();
        }

        private void RedoCommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            if (_inkCanvasCommandStack == null)
            {
                e.CanExecute = false;
                return;
            }
            // Enable only if there are items on the command stack
            e.CanExecute = _inkCanvasCommandStack.CanRedo;
        }

        /// <summary>
        /// Enabling undo/redo for selections moving or resizing.
        /// </summary>
        private void CurrentInkCanvas_SelectionMoving(object sender, InkCanvasSelectionEditingEventArgs e)
        {
            // Enforce stroke bounds to positive territory.
            Rect newRect = e.NewRectangle; Rect oldRect = e.OldRectangle;

            if (newRect.Top < 0d || newRect.Left < 0d)
            {
                Rect newRect2 =
                    new Rect(newRect.Left < 0d ? 0d : newRect.Left,
                                newRect.Top < 0d ? 0d : newRect.Top,
                                newRect.Width,
                                newRect.Height);

                e.NewRectangle = newRect2;
            }
            ActiveStory.UI.Commands.CommandItem item = new ActiveStory.UI.Commands.SelectionMovedOrResizedCI(_inkCanvasCommandStack, CurrentInkCanvas.GetSelectedStrokes(), newRect, oldRect, _editingOperationCount);
            _inkCanvasCommandStack.Enqueue(item);
        }

        /// <summary>
        /// Enabling undo/redo for selections moving or resizing.
        /// </summary>
        private void CurrentInkCanvas_SelectionResizing(object sender, InkCanvasSelectionEditingEventArgs e)
        {
            // Enforce stroke bounds to positive territory.
            Rect newRect = e.NewRectangle; Rect oldRect = e.OldRectangle;

            if (newRect.Top < 0d || newRect.Left < 0d)
            {
                Rect newRect2 =
                    new Rect(newRect.Left < 0d ? 0d : newRect.Left,
                                newRect.Top < 0d ? 0d : newRect.Top,
                                newRect.Width,
                                newRect.Height);

                e.NewRectangle = newRect2;
            }
            ActiveStory.UI.Commands.CommandItem item = new ActiveStory.UI.Commands.SelectionMovedOrResizedCI(_inkCanvasCommandStack, CurrentInkCanvas.GetSelectedStrokes(), newRect, oldRect, _editingOperationCount);
            _inkCanvasCommandStack.Enqueue(item);
        }

        /// <summary>
        /// Enabling undo/redo for changes to the strokes collection.
        /// </summary>
        void Strokes_StrokesChanged(object sender, System.Windows.Ink.StrokeCollectionChangedEventArgs e)
        {
            System.Windows.Ink.StrokeCollection added = new System.Windows.Ink.StrokeCollection(e.Added);
            System.Windows.Ink.StrokeCollection removed = new System.Windows.Ink.StrokeCollection(e.Removed);
            if (e.Added.Count > 1 || e.Removed.Count > 1)
                return;
            _editingOperationCount += e.Added.Count;
            _editingOperationCount += e.Removed.Count;
            ActiveStory.UI.Commands.CommandItem item = new ActiveStory.UI.Commands.StrokesAddedOrRemovedCI(_inkCanvasCommandStack, CurrentInkCanvas.EditingMode, added, removed, _editingOperationCount);
            _inkCanvasCommandStack.Enqueue(item);
        }
        #endregion

    }
}
